package com.c2b.algorithm.leetcode.lcr;

/**
 * <a href='https://leetcode.cn/problems/sort-list/description/'>排序链表(Sort List)</a>
 * <p>给你链表的头结点 head ，请将其按 升序 排列并返回 排序后的链表 。</p>
 *
 * <p>
 * <b>示例：</b>
 * <pre>
 * 示例 1：
 *      输入：head = [4,2,1,3]
 *      输出：[1,2,3,4]
 *
 * 示例 2：
 *      输入：head = [-1,5,3,4,0]
 *      输出：[-1,0,3,4,5]
 *
 * 示例 3：
 *      输入：head = []
 *      输出：[]
 * </pre>
 * </p>
 *
 * <p>
 * <b>提示：</b>
 *     <ul>
 *         <li>链表中节点的数目在范围 [0, 5 * 10^4] 内</li>
 *         <li>-10^5 <= Node.val <= 10^5</li>
 *     </ul>
 * </p>
 * <b>进阶：你可以在 O(n log n) 时间复杂度和常数级空间复杂度下，对链表进行排序吗？</b>
 *
 * @author c2b
 * @since 2024/3/20 14:26
 */
public class LCR077 {
    static class Solution {
        public ListNode sortList(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            ListNode slow = head;
            ListNode fast = head;
            while (fast.next != null && fast.next.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            ListNode list2 = slow.next;
            slow.next = null;
            return mergeTwoSortedList(sortList(head), sortList(list2));
        }

        /**
         * 合并两个有序链表
         */
        private ListNode mergeTwoSortedList(ListNode list1, ListNode list2) {
            if (list1 == null) {
                return list2;
            }
            if (list2 == null) {
                return list1;
            }
            ListNode dummyNode = new ListNode();
            ListNode currNode = dummyNode;
            while (list1 != null && list2 != null) {
                if (list1.val < list2.val) {
                    currNode.next = list1;
                    list1 = list1.next;
                } else {
                    currNode.next = list2;
                    list2 = list2.next;
                }
                currNode = currNode.next;
            }
            if (list1 == null) {
                currNode.next = list2;
            }
            if (list2 == null) {
                currNode.next = list1;
            }
            return dummyNode.next;
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        ListNode head1 = new ListNode(4);
        head1.next = new ListNode(2);
        head1.next.next = new ListNode(1);
        head1.next.next.next = new ListNode(3);

        ListNode head2 = new ListNode(-1);
        head2.next = new ListNode(5);
        head2.next.next = new ListNode(3);
        head2.next.next.next = new ListNode(4);
        head2.next.next.next.next = new ListNode(0);

        ListNode currNode1 = solution.sortList(head1);
        while (currNode1 != null) {
            System.out.print(currNode1.val + " -> ");
            currNode1 = currNode1.next;
        }
        System.out.println("null");

        ListNode currNode2 = solution.sortList(head2);
        while (currNode2 != null) {
            System.out.print(currNode2.val + " -> ");
            currNode2 = currNode2.next;
        }
        System.out.println("null");
    }
}
